package dfs_bfs;

import java.util.*;


public class lc210 {
    public static void main(String[] args) {
        findOrder2(4, new int[][]{{1,0},{2,0},{3,1},{3,2}});
    }

    public static int[] findOrder2(int numCourses, int[][] prerequisites) {
        //bfs
        List<Integer> list = new ArrayList<>();
        int[] count = new int[numCourses];
        List<List<Integer>> pre = new ArrayList<>();
        for (int i = 0; i < numCourses; i++) {
            pre.add(new ArrayList<>());
        }
        for (int i = 0; i < prerequisites.length; i++) {
            pre.get(prerequisites[i][1]).add(prerequisites[i][0]);
            count[prerequisites[i][0]]++;
        }
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < numCourses; i++) {
            if(count[i] == 0){
                queue.add(i);
            }
        }
        int[] re = new int[numCourses];
        while (!queue.isEmpty()){
            int t = queue.poll();
            list.add(t);
            numCourses--;
            for (int p : pre.get(t)) {
                count[p]--;
                if(count[p] == 0){
                    queue.add(p);

                }
            }
        }
        if(numCourses != 0)
            return new int[]{};
        System.out.println(list);
        for (int i = 0; i < list.size(); i++) {
            re[i] = list.get(i);
        }
        return re;
    }


    public static int[] findOrder(int numCourses, int[][] prerequisites) {
        //dfs
        List<Integer> list = new ArrayList<>();
        int[] used = new int[numCourses];
        List<List<Integer>> pre = new ArrayList<>();
        for (int i = 0; i < numCourses; i++) {
            pre.add(new ArrayList<>());
        }
        for (int i = 0; i < prerequisites.length; i++) {
            pre.get(prerequisites[i][0]).add(prerequisites[i][1]);
        }
        for (int i = 0; i < numCourses; i++) {
            if( !dfs(used, pre, i, list))
                return new int[]{};
        }
        int[] re = new int[numCourses];
        System.out.println(list);
        for (int i = 0; i < list.size(); i++) {
            re[i] = list.get(i);
        }
        return re;
    }
    public static boolean dfs(int[] used, List<List<Integer>> pre, int i, List<Integer> list){
        if(used[i] == 2)
            return false;
        if(used[i] == 1)
            return true;
        used[i] = 2;
        for (int j = 0; j < pre.get(i).size(); j++) {
            if( !dfs(used, pre, pre.get(i).get(j), list))
                return false;
        }
        used[i] = 1;
        list.add(i);
        return true;
    }
}
